// 匹配小胡子语法 {{xxx}}, 得到一个数组，数组第一项是整个正则的匹配，第二项是第一个分组匹配到的
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;

// 处理 attr
function genProps(attrs) {
  let str = "";
  for (let i = 0; i < attrs.length; i++) {
    let attr = attrs[i];
    // style 的方式不一样,需要将多个值合并到一起
    if (attr.name === "style") {
      let obj = {};
      attr.value.split(";").forEach((item) => {
        let [key, value] = item.split(":");
        obj[key] = value;
      });
      attr.value = obj; // {style : {color: red; width: 100px}}
    }
    str += `${attr.name}:${JSON.stringify(attr.value)},`; // {a: "xxx",b:"fd"}
  }
  return `{${str.slice(0, -1)}}`;
}

// 处理 children,
function genChildren(el) {
  let children = el.children;
  if (!children) {
    return false;
  }
  return children.map((child) => gen(child)).join(",");
}

// 可能是文本节点，也可能是元素节点
function gen(node) {
  if (node.type === 1) {
    // 元素节点就递归解析
    return generate(node);
  } else if (node.type === 3) {
    // 文本, 有三种方式，1.正常普通文本，2.{{}}文本, 3.两者混合
    let text = node.text;
    if (defaultTagRE.test(text)) {
      //  匹配{{}}, 得到如： _v(_s(name)+'aa'+_s(xxx)+'哈哈')  _s 代表 stringify
      // (/\d[a-zA-Z]/g).exec('aa2edj3djie7788')  ===>  ["2e", index: 2, input: "aa2edj3djie7788", groups: undefined]
      let tokens = [];
      let match;
      let index = 0;
      let lastIndex = (defaultTagRE.lastIndex = 0);
      while ((match = defaultTagRE.exec(text))) {
        // match[1] 为匹配到的 {{xxx}} 中的 xxx
        index = match.index;
        // lastIndex: 本次开始匹配位置； index: 实际匹配到结果的位置，index > lastIndex 表示 {{xxx}} 之前有普通文本
        if (index > lastIndex) {
          // 将 {{xxx}} 前的普通文本放进去
          tokens.push(JSON.stringify(text.slice(lastIndex, index)));
        }
        // 将 {{xxx}} 中的 xxx 放进去
        tokens.push(`_s(${match[1].trim()})`);
        lastIndex = index + match[0].length; // lastIndex 是下一次开始匹配的位置
      }
      // 将最后的{{xxx}} 后的普通文本放进去
      if (lastIndex < text.length) {
        tokens.push(JSON.stringify(text.slice(lastIndex)));
      }
      return `_v(${tokens.join("+")})`; // 字符串拼接  _v("你好"+_s(age)+"hello"+_s(name)+"world")
    } else {
      // 直接就是正常普通文本
      return `_v(${JSON.stringify(text)})`;
    }
  }
}

// 处理元素节点
export function generate(el) {
  let children = genChildren(el);
  let code = `_c('${el.tag}',${
    el.attrs.length ? genProps(el.attrs) : "undefined"
  }${children ? "," + children : ""})`;
  return code;
}
